﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Routing;
using Xunit;

namespace JoelAbrahamsson.Web.Tests
{
    public class InboundRoutingTests
    {
        [Fact]
        public void Slash_GoesTo_HomeIndexWith10Entries()
        {
            TestRoute("~/", new
            {
                controller = "Home",
                action = "Index",
                entryCount = 10
            });
        }

        [Fact]
        public void Slash3Pages_GoesTo_HomeIndexWith30Entries()
        {
            TestRoute("~/30entries", new
            {
                controller = "Home",
                action = "Index",
                entryCount = 30
            });
        }

        [Fact]
        public void EntrySlashSlugValue_GoesTo_EntryWithIndexAction()
        {
            TestRoute("~/entry/slugValue", new
            {
                controller = "Entry",
                action = "Index",
                slug = "slugValue"
            });
        }

        [Fact]
        public void EntrySlashSlugValueSlashAction_GoesTo_EntryWithAction()
        {
            TestRoute("~/entry/slugValue/actionName", new
            {
                controller = "Entry",
                action = "actionName",
                slug = "slugValue"
            });
        }

        [Fact]
        public void SlashControllerName_GoesTo_Controller()
        {
            TestRoute("~/controllerName", new
            {
                controller = "controllerName",
                action = "Index"
            });
        }

        private void TestRoute(string url, object expectedValues)
        {
            // Arrange: Prepare the route collection and a mock request context
            RouteCollection routes = new RouteCollection();
            Global.RegisterRoutes(routes);
            var mockHttpContext = new Moq.Mock<HttpContextBase>();
            var mockRequest = new Moq.Mock<HttpRequestBase>();
            mockHttpContext.Setup(x => x.Request).Returns(mockRequest.Object);
            mockRequest.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(url);

            // Act: Get the mapped route
            RouteData routeData = routes.GetRouteData(mockHttpContext.Object);

            // Assert: Test the route values against expectations
            Assert.NotNull(routeData);
            var expectedDict = new RouteValueDictionary(expectedValues);
            foreach (var expectedVal in expectedDict)
            {
                if (expectedVal.Value == null)
                    Assert.Null(routeData.Values[expectedVal.Key]);
                else
                    Assert.Equal(expectedVal.Value.ToString(),
                                 routeData.Values[expectedVal.Key].ToString());
            }
        }
    }
}
